package jsr292.java.lang.invoke;

import jsr292.java.lang.invoke.MethodHandles.Lookup;

// all public methods are entry points for the backport runtime
// don't modify the methods without changing the code in OnlineWeaver.
public class ConstantMethodHandles {
    public static MethodHandle getField(Lookup lookup, Class<?> declaringClass, String name, Class<?> type) {
        try {
            return lookup.findGetter(declaringClass, name, type);
        } catch (NoSuchFieldException e) {
            throw (NoSuchFieldError)new NoSuchFieldError().initCause(e);
        } catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle getStatic(Lookup lookup, Class<?> declaringClass, String name, Class<?> type) {
        try {
            return lookup.findStaticGetter(declaringClass, name, type);
        } catch (NoSuchFieldException e) {
            throw (NoSuchFieldError)new NoSuchFieldError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle putField(Lookup lookup, Class<?> declaringClass, String name, Class<?> type) {
        try {
            return lookup.findSetter(declaringClass, name, type);
        } catch (NoSuchFieldException e) {
            throw (NoSuchFieldError)new NoSuchFieldError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle putStatic(Lookup lookup, Class<?> declaringClass, String name, Class<?> type) {
        try {
            return lookup.findStaticSetter(declaringClass, name, type);
        } catch (NoSuchFieldException e) {
            throw (NoSuchFieldError)new NoSuchFieldError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle invokeVirtual(Lookup lookup, Class<?> declaringClass, String name, String desc) {
        try {
            return lookup.findVirtual(declaringClass, name, methodType(lookup, desc));
        } catch (NoSuchMethodException e) {
            throw (NoSuchMethodError)new NoSuchMethodError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle invokeStatic(Lookup lookup, Class<?> declaringClass, String name, String desc) {
        try {
            return lookup.findStatic(declaringClass, name, methodType(lookup, desc));
        } catch (NoSuchMethodException e) {
            throw (NoSuchMethodError)new NoSuchMethodError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle invokeSpecial(Lookup lookup, Class<?> declaringClass, String name, String desc, Class<?> callerClass) {
        try {
            return lookup.findSpecial(declaringClass, name, methodType(lookup, desc), callerClass);
        } catch (NoSuchMethodException e) {
            throw (NoSuchMethodError)new NoSuchMethodError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    public static MethodHandle invokeConstructor(Lookup lookup, Class<?> declaringClass, String desc) {
        try {
            return lookup.findConstructor(declaringClass, methodType(lookup, desc));
        } catch (NoSuchMethodException e) {
            throw (NoSuchMethodError)new NoSuchMethodError().initCause(e);
        }  catch(IllegalAccessException e) {
            throw (IllegalAccessError)new IllegalAccessError().initCause(e);
        }
    }
    
    // this code can also be found in BootstrapCallSite
    // I decide to duplicate it to avoid unnecessary class loading
    private static MethodType methodType(Lookup lookup, String desc) {
        return MethodType.fromMethodDescriptorString(desc, lookup.lookupClass().getClassLoader());
    }
}
